﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Model;
using MonteCarloAlgorithm.Distribution;

namespace MonteCarloAlgorithm
{
    /// <summary>
    /// Classe que realiza a simulação de monte carlo, podendo chamar diferentes diferentes formas de distribuição de dados
    /// </summary>
    public static class MonteCarloSimulation
    {
        #region Epic

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iterationNumber"></param>
        /// <param name="projectItens"></param>
        /// <returns></returns>
        public static IList<int> monteCarloInt(int iterationNumber, IList<Epic> projectItens)
        {
            Random r = new Random();
            IList<int> resultsValues = new List<int>();
            for (int i = 0; i < iterationNumber; i++)
            {
                var result = 0;
                foreach (Epic projectItem in projectItens)
                {
                    double minimun = (double)projectItem.MelhorCaso;
                    double mostProbable = (double)projectItem.CasoMedio;
                    double maximum = (double)projectItem.PiorCaso;
                    
                    result += (int)Triangular.triangular(minimun, mostProbable, maximum,r);
                }
                resultsValues.Add(result);
            }

            return resultsValues;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iterationNumber"></param>
        /// <param name="projectItens"></param>
        /// <returns></returns>
        public static IList<double> monteCarloDouble(int iterationNumber, IList<Epic> projectItens)
        {
            Random r = new Random();
            IList<double> resultsValues = new List<double>();
            for (int i = 0; i < iterationNumber; i++)
            {
                var result = 0.0;
                foreach (Epic projectItem in projectItens)
                {
                    double minimun = (double)projectItem.PiorCaso;
                    double mostProbable = (double)projectItem.CasoMedio;
                    double maximum = (double)projectItem.MelhorCaso;

                    result += Triangular.triangular(minimun, mostProbable, maximum, r);
                }
                resultsValues.Add(result);
            }

            return resultsValues;
        }

        #endregion

        #region History

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iterationNumber"></param>
        /// <param name="projectItens"></param>
        /// <returns></returns>
        public static IList<int> monteCarloInt(int iterationNumber, IList<History> projectItens)
        {
            Random r = new Random();
            IList<int> resultsValues = new List<int>();
            for (int i = 0; i < iterationNumber; i++)
            {
                var result = 0;
                foreach (History projectItem in projectItens)
                {
                    double minimun = (double)projectItem.MelhorCaso;
                    double mostProbable = (double)projectItem.CasoMedio;
                    double maximum = (double)projectItem.PiorCaso;

                    var t = (int)Triangular.triangular(minimun, mostProbable, maximum, r);

                    result += t;
                }
                resultsValues.Add(result);
            }

            return resultsValues;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iterationNumber"></param>
        /// <param name="projectItens"></param>
        /// <returns></returns>
        public static IList<double> monteCarloDouble(int iterationNumber, IList<History> projectItens)
        {
            Random r = new Random();
            IList<double> resultsValues = new List<double>();
            for (int i = 0; i < iterationNumber; i++)
            {
                var result = 0.0;
                foreach (History projectItem in projectItens)
                {
                    double minimun = (double)projectItem.PiorCaso;
                    double mostProbable = (double)projectItem.CasoMedio;
                    double maximum = (double)projectItem.MelhorCaso;

                    result += Triangular.triangular(minimun, mostProbable, maximum, r);
                }
                resultsValues.Add(result);
            }

            return resultsValues;
        }

        #endregion

        #region Task

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iterationNumber"></param>
        /// <param name="projectItens"></param>
        /// <returns></returns>
        public static IList<int> monteCarloInt(int iterationNumber, IList<Task> projectItens)
        {
            Random r = new Random();
            IList<int> resultsValues = new List<int>();
            for (int i = 0; i < iterationNumber; i++)
            {
                var result = 0;
                foreach (Task projectItem in projectItens)
                {
                    double minimun = (double)projectItem.MelhorCaso;
                    double mostProbable = (double)projectItem.CasoMedio;
                    double maximum = (double)projectItem.PiorCaso;

                    result += (int)Triangular.triangular(minimun, mostProbable, maximum, r);
                }
                resultsValues.Add(result);
            }

            return resultsValues;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iterationNumber"></param>
        /// <param name="projectItens"></param>
        /// <returns></returns>
        public static IList<double> monteCarloDouble(int iterationNumber, IList<Model.Task> projectItens)
        {
            Random r = new Random();
            IList<double> resultsValues = new List<double>();
            for (int i = 0; i < iterationNumber; i++)
            {
                var result = 0.0;
                foreach (Model.Task projectItem in projectItens)
                {
                    double minimun = (double)projectItem.PiorCaso;
                    double mostProbable = (double)projectItem.CasoMedio;
                    double maximum = (double)projectItem.MelhorCaso;

                    result += Triangular.triangular(minimun, mostProbable, maximum, r);
                }
                resultsValues.Add(result);
            }

            return resultsValues;
        }

        #endregion
    }
}
